package com.kingint.web.portal.serve.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kingint.common.unitedresult.K;
import com.kingint.mbg.bas.entity.*;
import com.kingint.mbg.bas.mapper.BasFloorMapper;
import com.kingint.mbg.bas.mapper.BasRoomMapper;
import com.kingint.mbg.bas.mapper.BasWorkOrderTypeMapper;
import com.kingint.mbg.dto.BackQueryParam;
import com.kingint.mbg.dto.WorkOrderFront;
import com.kingint.mbg.ser.entity.*;
import com.kingint.mbg.ser.mapper.*;
import com.kingint.mbg.sys.entity.UmsMember;
import com.kingint.web.domain.FrontParam;
import com.kingint.web.portal.serve.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kingint.web.sys.service.UmsAdminService;
import com.kingint.web.util.DateUtil;
import com.kingint.web.util.WorkType;
import com.kingint.web.vo.RepairBean;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 相关工单总表 服务实现类
 * </p>
 *
 * @author wxh
 * @since 2021-01-08
 */
@Service
@Slf4j
public class SerWorkOrderServiceImpl extends ServiceImpl<SerWorkOrderMapper, SerWorkOrder> implements SerWorkOrderService {

    @Resource
    private SerWorkOrderMapper serWorkOrderMapper;
    @Resource
    private UmsAdminService adminService;
    @Resource
    private BasRoomMapper roomMapper;
    @Resource
    private BasFloorMapper floorMapper;
    @Resource
    private SerDepartmentRepairMapper departmentRepairMapper;
    @Resource
    private SerRushHouseMapper rushHouseMapper;
    @Resource
    private SerCheckRoomMapper checkRoomMapper;
    @Resource
    private SerServiceOrderMapper serviceOrderMapper;
    @Resource
    private SerRoomCleanMapper roomCleanMapper;
    @Resource
    private DepartmentRepairService departmentRepairService;
    @Resource
    private ServiceOrderService serviceOrderService;
    @Resource
    private SerReceiveWorkMiddleMapper receiveWorkMiddleMapper;
    @Resource
    private SerMessageReplyMiddleMapper messageReplyMiddleMapper;
    @Resource
    private RushHouseService rushHouseService;
    @Resource
    private BasWorkOrderTypeMapper basWorkOrderTypeMapper;
    @Resource
    private TaskService taskService;
    @Resource
    private RepairBean repairBean;
    @Resource
    private SerSendMessageMapper sendMessageMapper;

    @Override
    public Object getAllWorkOrderList(Integer pageNum, Integer pageSize) {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("当前账号没有关联对应的酒店id");
            return K.error().data("当前账号没有关联对应的酒店id");
        }
        List<Integer> orderStatus = new ArrayList<>();
        orderStatus.add(2);//处理中
        orderStatus.add(3);//待验收
        orderStatus.add(6);//待确认

        BackQueryParam param = new BackQueryParam();
        param.setHotelId(hotelId);
        param.setMemberId(currentMember.getId());
        param.setIsOther(1);//其余状态
        param.setIsWait(1);//待处理状态
        //查询相关的工单信息，根据时间排序
        IPage<SerWorkOrder> page = new Page<>(pageNum, pageSize);
        param.setOrderStatus(orderStatus);//对应的工单状态
        param.setIsSend(1);//需要
        return getWorkOrderFront(page, param);
    }

    @Override
    public Object getFrontSomethingNumber() {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer workStatus = currentMember.getWorkStatus();//上班状态
        Date loginTime = currentMember.getLoginTime();//登录时间
        ///TODO 待处理 打卡还要设置配置表

        Map<String, Object> map = new HashMap<>();
        if (workStatus == 0) {//下班状态，要打卡
            map.put("workStatus", 0);
        } else if (workStatus == 1) {//上班状态 判断时间是否是今天的
            long time = DateUtil.getDate(loginTime).getTime();//打卡时间
            long time1 = DateUtil.getDate(new Date()).getTime();//当前时间
            if (time == time1) {//已经打卡
                map.put("workStatus", 1);//上下班状态（0，下班，1，上班）
            } else {//不等于，没有打卡
                map.put("workStatus", 0);//下班
            }
        }
        //通知数（待阅读的）
        //查询对应的通知数
        Integer hotelId = currentMember.getHotelId();
        if (!StringUtils.isEmpty(hotelId)) {
            BackQueryParam param = new BackQueryParam();
            param.setHotelId(hotelId);
            param.setReceiveUserId(currentMember.getId());
            param.setIsRead(0);//未读
            List<SerSendMessage> sendMessageList = serWorkOrderMapper.getSendMessageList(param);
            map.put("message", sendMessageList.size());

            //抢单数当前状态为1的
            QueryWrapper<SerWorkOrder> wrapper = new QueryWrapper<>();
            wrapper.eq("hotel_id", hotelId)
                    .eq("status", 0)
                    .eq("order_status", 1);
            Integer integer = serWorkOrderMapper.selectCount(wrapper);
            map.put("orderNumber", integer);

            //验收数
            BackQueryParam queryParam = new BackQueryParam();
            queryParam.setHotelId(hotelId);
            queryParam.setMemberId(currentMember.getId());
            List<Integer> list=new ArrayList<>();
            list.add(3);//待审核
            queryParam.setOrderStatus(list);
            Integer number = serWorkOrderMapper.getWaitHandleNumber(queryParam);
            map.put("checkNumber",number);
        } else {
            log.debug("该账号没有关联对应的酒店id");
            map.put("message", 0);
            map.put("orderNumber", 0);
            map.put("checkNumber",0);
        }
        return K.ok().data(map);
    }

    /**
     * 接单
     *
     * @param frontParam
     * @return
     */
    @Override
    public Integer grabOrder(FrontParam frontParam) {
        String workTypeName = frontParam.getWorkTypeName();//工单类型名称
        if (workTypeName.contains(WorkType.repairName)) {//部门维修单
            return departmentRepairService.receiveOrder(frontParam.getBillId());
        } else if (workTypeName.contains(WorkType.serviceOrderName)) {//服务单
            return serviceOrderService.receiverServiceOrder(frontParam.getBillId());
        }
        log.debug("没有对应的工单类型：" + frontParam.toString());
        return 0;
    }

    @Override
    public Integer confirmOrder(FrontParam frontParam) {
        UmsMember currentMember = adminService.getCurrentMember();
        String workTypeName = frontParam.getWorkTypeName();
        if (workTypeName.contains(WorkType.sendMessageName)) {//发送消息回复
            SerMessageReplyMiddle middle = new SerMessageReplyMiddle();
            middle.setReply(1);//回复
            QueryWrapper<SerMessageReplyMiddle> wrapper = new QueryWrapper<>();
            wrapper.eq("send_message_id", frontParam.getBillId())
                    .eq("receive_user_id", currentMember.getId());
            return messageReplyMiddleMapper.update(middle, wrapper);
        }

        //相关工单确认，回复接口
        Integer workId = frontParam.getWorkId();
        //先查询是否还有当前工单，是否已经更换处理人
        QueryWrapper<SerReceiveWorkMiddle> wrapper = new QueryWrapper<>();
        wrapper.eq("work_id", workId)
                .eq("receive_user_id", currentMember.getId())
                .eq("status", 0);//未删除
        Integer integer = receiveWorkMiddleMapper.selectCount(wrapper);
        if (integer > 0) {
            if (workTypeName.contains(WorkType.rushHouseName)) {//赶房确认接单
                return rushHouseService.receiveOrderInfo(frontParam.getBillId());
            }
        }
        return 0;
    }

    @Override
    public List<BasWorkOrderType> getAllWorkType() {
        List<BasWorkOrderType> list = basWorkOrderTypeMapper.selectList(null);
        return list;
    }

    @Override
    public Object getWaitHandleOrderList(Integer pageNum, Integer pageSize) {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("当前账号没有关联对应的酒店id");
            return K.error().data("当前账号没有关联对应的酒店id");
        }
        BackQueryParam param = new BackQueryParam();
        param.setHotelId(hotelId);
        param.setMemberId(currentMember.getId());
        //查询相关的工单信息，根据时间排序
        IPage<SerWorkOrder> page = new Page<>(pageNum, pageSize);

        List<Integer> orderStatus = new ArrayList<>();
        orderStatus.add(3);//待验收
        param.setOrderStatus(orderStatus);
        IPage<SerWorkOrder> handleWorkList = serWorkOrderMapper.getWaitHandleWorkList(page, param);
        List<SerWorkOrder> records = handleWorkList.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            return handleSerWorkInfo(handleWorkList);
        }
        return null;
    }

    @Override
    public Integer examineOrder(FrontParam frontParam) {
        SerWorkOrder serWorkOrder = serWorkOrderMapper.selectById(frontParam.getWorkId());
        String processInstanceId = serWorkOrder.getProcessInstanceId();
        Task task = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        //完成验收checkStatus
        if (!StringUtils.isEmpty(task)) {
            Map<String, Object> map = new HashMap<>();
            map.put(repairBean.getRejectStatus(), frontParam.getCheckStatus());
            taskService.complete(task.getId(), map);
            return 1;
        }
        return 0;
    }

    @Override
    public Object getWaitWorkOrderList(Integer pageNum, Integer pageSize) {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("当前账号没有关联对应的酒店id");
            return K.error().data("当前账号没有关联对应的酒店id");
        }
        BackQueryParam param = new BackQueryParam();
        param.setHotelId(hotelId);
        param.setMemberId(currentMember.getId());
        param.setIsWait(1);//待接单
        //查询相关的工单信息，根据时间排序
        IPage<SerWorkOrder> page = new Page<>(pageNum, pageSize);
        param.setIsSend(0);//不需要群发通知
        return getWorkOrderFront(page, param);
    }

    @Override
    public Object getAllUserBillList(Integer type, Integer pageNum, Integer pageSize) {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("当前账号没有关联对应的酒店id");
            return K.error().data("当前账号没有关联对应的酒店id");
        }
        BackQueryParam param = new BackQueryParam();
        param.setHotelId(hotelId);//酒店id
        param.setMemberId(currentMember.getId());//用户id
        List<Integer> orderStatus = new ArrayList<>();
        if(type==0){//0,全部，1,待确认，2，处理中，3，审核中，4，完成
            orderStatus.add(2);//处理中
            orderStatus.add(3);//待验收
            orderStatus.add(6);//待确认
            orderStatus.add(5);//已完成

        }else if(type==1){//待确认
            orderStatus.add(6);
        }else if(type==2){
            orderStatus.add(2);
        }else if(type==3){
            orderStatus.add(3);
        }else if(type==4){
            orderStatus.add(5);
        }
        IPage<SerWorkOrder> page = new Page<>(pageNum, pageSize);
        param.setOrderStatus(orderStatus);//对应的工单状态
        param.setIsOther(1);
        return getWorkOrderFront(page, param);
    }

    /**
     * 查询相关的信息，进行相关的处理
     * @param page
     * @param param
     * @return
     */
    private IPage<WorkOrderFront> getWorkOrderFront(IPage<SerWorkOrder> page, BackQueryParam param) {
        IPage<SerWorkOrder> allWorkList = serWorkOrderMapper.getAllWorkList(page, param);
        List<SerWorkOrder> records = allWorkList.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            return handleSerWorkInfo(allWorkList);
        }
        return null;
    }

    /**
     * 处理各种工单相关首页展示的内容
     *
     * @param handleWorkList
     */
    private IPage<WorkOrderFront> handleSerWorkInfo(IPage<SerWorkOrder> handleWorkList) {
        List<SerWorkOrder> records = handleWorkList.getRecords();
        List<WorkOrderFront> list = new ArrayList<>();
        for (SerWorkOrder info : records) {
            WorkOrderFront front = new WorkOrderFront();
            BeanUtils.copyProperties(info, front);
            front.setWorkId(info.getId());
            //处理相关的信息 查询楼层，房间号 查询相关工单的信息
            Integer roomId = info.getRoomId();
            if(!StringUtils.isEmpty(roomId)){
                BasRoom basRoom = roomMapper.selectById(roomId);
                front.setRoomNum(basRoom.getRoomNum());
                //查询对应楼层
                Integer floorId = basRoom.getFloorId();
                BasFloor basFloor = floorMapper.selectById(floorId);
                front.setFloorName(basFloor.getFloorName());
            }
            //查询对应工单的内容
            String workTypeName = info.getWorkTypeName();//工单类型名称
            if (workTypeName.contains(WorkType.repairName)) {//部门维修
                handleRepairBill(front);
            } else if (workTypeName.contains(WorkType.checkRoomName)) {//查房自查
                //先不要相关内容的只展示相关的房间楼层
                handleCheckRoomBill(front);
            } else if (workTypeName.contains(WorkType.rushHouseName)) {//赶房
                handleRushHouse(front);
            } else if (workTypeName.contains(WorkType.serviceOrderName)) {//服务工单
                handleServiceOrder(front);
            } else if (workTypeName.contains(WorkType.roomCleanName)) {//客房清洁
                handleRoomClean(front);
            } else if (workTypeName.contains(WorkType.sendMessageName)) {//群发通知
                handleMessage(front);
            }
            list.add(front);//添加集合
        }
        IPage<WorkOrderFront> frontIPage = new Page<>();
        frontIPage.setRecords(list);
        frontIPage.setPages(handleWorkList.getPages());
        frontIPage.setCurrent(handleWorkList.getCurrent());
        frontIPage.setSize(handleWorkList.getSize());
        frontIPage.setTotal(handleWorkList.getTotal());
        return frontIPage;
    }

    /**
     * 处理群发通知信息
     *
     * @param front
     */
    private void handleMessage(WorkOrderFront front) {
        Integer workId = front.getWorkId();
        QueryWrapper<SerSendMessage> wrapper = new QueryWrapper<>();
        wrapper.eq("work_id", workId);
        SerSendMessage serSendMessage = sendMessageMapper.selectOne(wrapper);
        if(!StringUtils.isEmpty(serSendMessage)){
            front.setTitle(serSendMessage.getTitle());//标题名称
            front.setContent(serSendMessage.getContent());
            front.setBillId(serSendMessage.getId());
        }
    }

    /**
     * 客房清洁相关内容
     *
     * @param front
     */
    private void handleRoomClean(WorkOrderFront front) {
        Integer workId = front.getWorkId();
        QueryWrapper<SerRoomClean> wrapper = new QueryWrapper<>();
        wrapper.eq("work_id", workId);
        SerRoomClean serRoomClean = roomCleanMapper.selectOne(wrapper);
        front.setBillId(serRoomClean.getId());
        front.setContent(serRoomClean.getNote());
    }

    /**
     * 处理服务工单相关的内容
     *
     * @param front
     */
    private void handleServiceOrder(WorkOrderFront front) {
        Integer workId = front.getWorkId();
        QueryWrapper<SerServiceOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("work_id", workId);
        SerServiceOrder serviceOrder = serviceOrderMapper.selectOne(wrapper);
        //处理服务内容
        front.setBillId(serviceOrder.getId());
        String content = serviceOrder.getServiceClassContent();
        if (!StringUtils.isEmpty(content)) {
            List<BasServiceClass> list = JSONObject.parseArray(content, BasServiceClass.class);
            StringBuffer buffer = new StringBuffer();
            for (int i = 0; i < list.size(); i++) {
                String name = list.get(i).getName();
                if (!StringUtils.isEmpty(name)) {
                    buffer.append(name);
                    if (i < list.size()) {
                        buffer.append(";");
                    }
                }
            }
            front.setContent(buffer.toString());
        }
    }

    /**
     * 处理赶房相关内容
     *
     * @param front
     */
    private void handleRushHouse(WorkOrderFront front) {
        Integer workId = front.getWorkId();
        QueryWrapper<SerRushHouse> wrapper = new QueryWrapper<>();
        wrapper.eq("work_id", workId);
        SerRushHouse serRushHouse = rushHouseMapper.selectOne(wrapper);
        front.setBillId(serRushHouse.getId());
        front.setIsSync(serRushHouse.getIsSync());
    }

    /**
     * 处理查房自查工单
     *
     * @param front
     */
    private void handleCheckRoomBill(WorkOrderFront front) {
        Integer workId = front.getWorkId();
        QueryWrapper<SerCheckRoom> wrapper = new QueryWrapper<>();
        wrapper.eq("work_id", workId);
        SerCheckRoom serCheckRoom = checkRoomMapper.selectOne(wrapper);
        front.setBillId(serCheckRoom.getId());
    }

    /**
     * 处理维修工单相关的信息
     *
     * @param front
     */
    private void handleRepairBill(WorkOrderFront front) {
        Integer workId = front.getWorkId();
        QueryWrapper<SerDepartmentRepair> wrapper = new QueryWrapper<>();
        wrapper.eq("work_id", workId);
        SerDepartmentRepair repair = departmentRepairMapper.selectOne(wrapper);
        front.setBillId(repair.getId());//对应的id
        String warrantyContent = repair.getWarrantyContent();
        if (!StringUtils.isEmpty(warrantyContent)) {
            List<BasWarrantyItems> items = JSONObject.parseArray(warrantyContent, BasWarrantyItems.class);
            StringBuffer buffer = new StringBuffer();
            for (int i = 0; i < items.size(); i++) {
                String name = items.get(i).getWarrantyName();
                if (!StringUtils.isEmpty(name)) {
                    buffer.append(name);
                    if (i < items.size()) {
                        buffer.append(";");
                    }
                }
            }
            front.setContent(buffer.toString());
        }
    }
}
